package cn.dzh.model.dto;

import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.validator.internal.engine.path.NodeImpl;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @version V1.0
 * @description: 统一返回结果类，用于封装后端接口返回给前端的数据格式
 * @author: dzd
 * @date: 2023/9/7
 */
@Data
@Accessors(chain = true)
public class HttpResult {
    /**
     * 返回的状态码，0表示成功，其他表示失败
     */
    private int code;
    /**
     * 返回的消息，一般用于返回错误信息
     */
    private String msg;
    /**
     * 返回的数据，可以是任意类型，如果是Map类型，可以使用put方法添加数据
     */
    private Object data;

    public HttpResult put(String key, Object value) {
        if (data==null || data instanceof Map){
            if (data==null){
                data = new HashMap<String,Object>();
            }
            ((Map)data).put(key,value);
        }
        return this;
    }

    public HttpResult() {
    }

    public static HttpResult ok(String msg,Object data){
        return new HttpResult(0,msg,data);
    }

    public static HttpResult ok(String msg){
        return HttpResult.ok(msg,null);
    }

    public static HttpResult ok(){
        return HttpResult.ok("成功");
    }

    public static HttpResult error(int code,String msg){
        return HttpResult.error(code,msg,new HashMap<>());
    }


    public static HttpResult error(int code,String msg,Object data){
        return new HttpResult(code,msg,data);
    }

    public HttpResult(int code, String message) {
        this.code = code;
        this.msg = message;
    }

    public HttpResult(int code, Object data) {
        this.code = code;
        this.data = data;
    }

    public HttpResult(int code, String message, Object data) {
        this.code = code;
        this.msg = message;
        this.data = data;
    }



    public static HttpResult error(int code, String msg, BindException e){
        HttpResult rs = error(code, msg);
        Map<String, ArrayList<Object>> errorMap = new HashMap<>();
        for (FieldError fieldError : e.getFieldErrors()) {
            String field = fieldError.getField();
            String message = fieldError.getDefaultMessage();
            if (!errorMap.containsKey(field)){
                errorMap.put(field, new ArrayList<>());
            }
            errorMap.get(field).add(message);
        }
        rs.setData(errorMap);
        return rs;
    }

    public static HttpResult error(int code, String msg, ConstraintViolationException e){
        HttpResult rs = error(code, msg);
        Map<String, ArrayList<Object>> errorMap = new HashMap<>();
        for (ConstraintViolation<?> violation : e.getConstraintViolations()) {
            PathImpl path =(PathImpl) violation.getPropertyPath();
            NodeImpl node = path.getLeafNode();
            String field = node.getName();
            String message = violation.getMessage();
            if (!errorMap.containsKey(field)){
                errorMap.put(field, new ArrayList<>());
            }
            errorMap.get(field).add(message);
        }
        rs.setData(errorMap);
        return rs;
    }

    public String getMessage() {
        return this.msg;
    }
}
